



import datetime
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait as wd
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchWindowException, TimeoutException, \
    NoAlertPresentException, NoSuchFrameException, NoSuchElementException

from utils.clipboard import ClipBoard
from utils.keyboard import KeyBoard
from utils.parseConFile import ParseConFile
from utils.parseExcelFile import ParseExcel


class BasePage(object):
    """
    结合显示等待封装一些selenium 内置方法
    """
    cf = ParseConFile()
    excel = ParseExcel()

    def __init__(self, driver, outTime=30):
        self.byDic = {
            'id': By.ID,
            'name': By.NAME,
            'class': By.CLASS_NAME,
            'xpath': By.XPATH,
            'link_text': By.LINK_TEXT,
            'tag_name': By.TAG_NAME,
            'css': By.CSS_SELECTOR
        }
        self.driver = driver
        self.outTime = outTime

    def screenshot(self, filename):
        """自动截图功能"""
        file_path = './pic/'
        now = datetime.datetime.now().strftime("%Y-%m-%d %H_%M_%S")
        # '获取当前时间'
        self.driver.get_screenshot_as_file(file_path + filename + '.png')

    def findElement_old(self, by, locator):
        """
        find alone element
        :param by: eg: id, name, xpath, css.....
        :param locator: id, name, xpath for str
        :return: element object
        修改过return
        """
        try:
            print('[Info:Starting find the element "{}" by "{}"!]'.format(locator, by))
            element = wd(self.driver, self.outTime).until(lambda x: x.find_element(by, locator))
        except TimeoutException as t:
            print('error: found "{}" timeout!'.format(locator), t)
        except NoSuchWindowException as e:
            print('error: no such "{}"'.format(locator), e)
        except Exception as e:
            print(f'find element error, {e}')
        else:
            print('[Info:Had found the element "{}" by "{}"!]'.format(locator, by))
            return element

    def findElement(self, by, locator):
        """
        find alone element
        :param by: eg: id, name, xpath, css.....
        :param locator: id, name, xpath for str
        :return: element object
        返回第一个可见element
        """
        if by.lower() in self.byDic:

            try:
                print('[Info:Starting find the element "{}" by "{}"!]'.format(locator, by))
                # element = wd(self.driver, self.outTime).until(lambda x: x.find_element(by, locator))
                element = wd(self.driver, self.outTime).until(lambda x: x.find_element(self.byDic[by], locator))
                # element = self.driver.find_element(self.byDic[by], locator)
            except TimeoutException as t:
                print('error: found "{}" timeout!'.format(locator), t)
                return None
            except NoSuchWindowException as e:
                print('error: no such "{}"'.format(locator), e)
                return None
            except Exception as e:
                print(f'find element error, {e}')
                return None
            else:
                print('[Info:Had found the element "{}" by "{}"!]'.format(locator, by))
                return element
        else:
            print('the "{}" error!'.format(by))
            return None

    def findElement2(self, by, locator):
        # modify
        if by.lower() in self.byDic:
            try:
                print(f'by = {by} messold = {self.byDic[by]}')
                element = self.driver.find_element(self.byDic[by], locator)
            except TimeoutException:
                print('Error: element "{}" time out!'.format(locator))
                return None
            except NoSuchWindowException:
                print('Error: element "{}" not exsit!'.format(locator))
                return None
            else:
                return element
        else:
            print('the "{}" error!'.format(by))
            return None

    def findElements(self, by, locator):
        """
        find group elements
        :param by: eg: id, name, xpath, css.....
        :param locator: eg: id, name, xpath for str
        :return: elements object
        """
        try:
            print('[Info:start find the elements "{}" by "{}"!]'.format(locator, by))
            elements = self.driver.find_elements(self.byDic[by], locator)
        except TimeoutException as t:
            print(t)
        except NoSuchWindowException as e:
            print(e)
        except Exception as e:
            raise e
        else:
            # print('[Info:Had found the elements "{}" by "{}"!]'.format(locator, by))
            return elements

    def findElements_pri(self, by, locator):
        """
        find group elements
        :param by: eg: id, name, xpath, css.....
        :param locator: eg: id, name, xpath for str
        :return: elements object
        """
        try:
            print('[Info:start find the elements "{}" by "{}"!]'.format(locator, by))
            elements = wd(self.driver, self.outTime).until(lambda x: x.find_element(by, locator))
        except TimeoutException as t:
            print(t)
        except NoSuchWindowException as e:
            print(e)
        except Exception as e:
            raise e
        else:
            # print('[Info:Had found the elements "{}" by "{}"!]'.format(locator, by))
            return elements

    def isElementExsit(self, by, locator):
        """
        assert element if exist
        :param by: eg: id, name, xpath, css.....
        :param locator: eg: id, name, xpath for str
        :return: if element return True else return false
        """
        if by.lower() in self.byDic:
            try:
                wd(self.driver, self.outTime). \
                    until(EC.visibility_of_element_located((self.byDic[by], locator)))
            except TimeoutException:
                print('Error: element "{}" time out!'.format(locator))
                return False
            except NoSuchWindowException:
                print('Error: element "{}" not exsit!'.format(locator))
                return False
            except Exception as e:
                print(f'other error, {e}')
                return False
            return True
        else:
            print('the "{}" error!'.format(by))

    def isClick(self, by, locator):
        """判断是否可点击,返回元素对象"""
        if by.lower() in self.byDic:
            try:
                element = wd(self.driver, self.outTime). \
                    until(EC.element_to_be_clickable((self.byDic[by], locator)))
            except Exception:
                return False
            return element
        else:
            print('the "{}" error!'.format(by))

    def isAlertAndSwitchToIt(self):
        """
        assert alert if exsit
        :return: alert obj
        """
        try:
            re = wd(self.driver, self.outTime).until(EC.alert_is_present())
        except NoAlertPresentException:
            return False
        except Exception:
            return False
        return re

    def switchToFrame(self, by, locator):
        """判断frame是否存在，存在就跳到frame"""
        print('info:switching to iframe "{}"'.format(locator))
        if by.lower() in self.byDic:
            try:
                wd(self.driver, self.outTime). \
                    until(EC.frame_to_be_available_and_switch_to_it((self.byDic[by], locator)))
            except TimeoutException as t:
                print('error: found "{}" timeout！'.format(locator), t)
            except NoSuchFrameException as e:
                print('error: no such "{}"'.format(locator), e)
            except Exception as e:
                raise e
        else:
            print('the "{}" error!'.format(by))

    def switchToDefaultFrame(self):
        """返回默认的frame"""
        print('info:switch back to default iframe')
        try:
            self.driver.switch_to.default_content()
        except Exception as e:
            print(e)

    def getAlertText(self):
        """获取alert的提示信息"""
        if self.isAlertAndSwitchToIt():
            alert = self.isAlertAndSwitchToIt()
            return alert.text
        else:
            return None

    def getElementText(self, by, locator, name=None):
        """获取某一个元素的text信息"""
        try:
            element = self.findElement(by, locator)
            if name:
                return element.get_attribute(name)
            else:
                return element.text
        except:
            print('get "{}" text failed return None'.format(locator))
            return None

    def loadUrl(self, url):
        """加载url"""
        print('info: string upload url "{}"'.format(url))
        self.driver.get(url)

    def getSource(self):
        """获取页面源码"""
        return self.driver.page_source

    def sendKeys(self, by, locator, value=''):
        """写数据"""
        print('info:input "{}"'.format(value))
        try:
            element = self.findElement(by, locator)
            element.send_keys(value)
        except AttributeError as e:
            print(e)

    def clear(self, by, locator):
        """清理数据"""
        print('info:clearing value')
        try:
            element = self.findElement(by, locator)
            element.clear()
        except AttributeError as e:
            print(e)

    def click(self, by, locator):
        """点击某个元素"""
        if by.lower() in self.byDic:

            print('info:click "{}"'.format(locator))
            element = self.isClick(by, locator)
            if element:
                element.click()
            else:
                print('the "{}" unclickable!'.format(locator))

        else:
            print('the "{}" error!'.format(by))

    def sleep(self, num=0):
        """强制等待"""
        print('info:sleep "{}" seconds'.format(num))
        time.sleep(num)

    def ctrlV(self, value):
        """ctrl + V 粘贴"""
        print('info:pasting "{}"'.format(value))
        ClipBoard.setText(value)
        self.sleep(3)
        KeyBoard.twoKeys('ctrl', 'v')

    def enterKey(self):
        """enter 回车键"""
        print('info:keydown enter')
        KeyBoard.oneKey('enter')

    def waitElementtobelocated(self, by, locator):
        """显示等待某个元素出现，且可见"""
        print('info:waiting "{}" to be located'.format(locator))
        try:
            wd(self.driver, self.outTime).until(EC.visibility_of_element_located((self.byDic[by], locator)))
        except TimeoutException as t:
            print('error: found "{}" timeout！'.format(locator), t)
        except NoSuchWindowException as e:
            print('error: no such "{}"'.format(locator), e)
        except Exception as e:
            raise e

    def assertValueInSource(self, value):
        """断言某个关键字是否存在页面源码中"""
        print('info:assert "{}" in page source'.format(value))
        source = self.getSource()
        assert value in source, '关键字"{}"不存在源码中!'.format(value)

    def assertStringContainsValue(self, String, value):
        """断言某段字符串包含另一个字符串"""
        print('info:assert "{}" contains "{}"'.format(String, value))
        assert value in String, '"{}"不包含"{}"!'.format(String, value)

    @staticmethod
    def getSheet(sheetName):
        """获取某个sheet页的对象"""
        sheet = BasePage.excel.getSheetByName(sheetName)
        return sheet


if __name__ == "__main__":
    from selenium import webdriver

    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ['enable-automation', 'load-extension'])  # 屏蔽自动化受控提示 && 开发者提示
    options.add_argument("--start-maximized")  # 浏览器启动时窗口最大化
    driver = webdriver.Chrome(options=options)

    login = BasePage(driver, 10)
    login.loadUrl('http://192.168.81.79')


    time.sleep(30)

    driver.quit()
    # login.assert_login_button_exist('11')

